package com.dpp.service.impl;

import com.dpp.context.BaseContext;
import com.dpp.dto.OrderDTO;
import com.dpp.entity.*;
import com.dpp.mapper.*;
import com.dpp.result.Result;
import com.dpp.service.OrderService;

import com.dpp.service.ProductInfoService;
import com.dpp.service.TakeOrderService;
import com.dpp.utils.DownloadUtil;
import com.dpp.utils.UploadUtil;
import com.dpp.vo.HistoryOrderVO;
import com.dpp.vo.HomeLists;
import com.dpp.vo.HomeVO;
import com.dpp.vo.OrderVO;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private UploadUtil upLoadUtil;
    @Autowired
    private DownloadUtil downloadUtil;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private TakeOrderMapper takeOrderMapper;
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private UserMoneyMapper userMoneyMapper;
    @Autowired
    private WithdrawMapper withdrawMapper;
    @Autowired
    private CouponBookMapper couponBookMapper;
    @Autowired
    private ActivityRecordMapper activityRecordMapper;
    @Autowired
    private OrderCountMapper orderCountMapper;

    @Value("${dpp.order-path}")
    private String basePath;

    @Value("${dpp.server-path}")
    private String serverPath;

    @Autowired
    private TakeOrderService takeOrderService;

    /**
     * 发单
     *
     * @param orderDTO
     * @param
     */
    @Transactional
    public String insert(OrderDTO orderDTO, Integer status) {

        //获取openid
        String openid = BaseContext.getCurrentId();

        //获取图片资源数组
        MultipartFile[] files = orderDTO.getImages();
        //创建集合对象
        List<String> imgs = new ArrayList<>();
        //判断是否接收到图片
        if (files != null && files.length > 0) {
            //存储到本地
            uploadToLocal(files, imgs);
        }

        long number = System.currentTimeMillis();
        //对象构造
        Orders orders = Orders.builder().number(number)
                .openid(openid)
                .amount(orderDTO.getAmount())
                .orderStatus(status)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .expectTime(orderDTO.getExpectTime()).productId(orderDTO.getProductId()).count(orderDTO.getCount())
                .build();
        if (orderDTO.getIsUseDiscount()) {
            orders.setIsUseCoupon(1);
            orders.setCouponId(orderDTO.getCouponId());
        } else {
            orders.setIsUseCoupon(0);
        }
        //插入到订单表,并返回主键id
        orderMapper.insertToOrders(orders);

        //将多张图片及其他详细信息存入order_detail表中
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orders.getId());
        orderDetail.setPackageInfo(orderDTO.getPackageInfo());
        orderDetail.setRemark(orderDTO.getRemark());
        orderDetail.setPhone(orderDTO.getPhone());
        orderDetail.setAddress(orderDTO.getAddress());

        //添加到数据库中
        if (imgs.isEmpty()) {
            orderMapper.insertToOrderDetail(orderDetail);
        }
        for (int i = 0; i < imgs.size(); i++) {
            orderDetail.setImage(imgs.get(i));
            orderMapper.insertToOrderDetail(orderDetail);
        }


        //更新默认地址
        if (orderDTO.getProductId() < 3 || orderDTO.getProductId() > 6) {
            String address = orderDTO.getAddress();
            String phone = orderDTO.getPhone();
            AddressBook addressBook = addressMapper.selectByOpenidAndPhoneAndAddress(openid, phone, address);

            if (addressBook != null) {
                addressMapper.clearDA(openid);
                addressBook.setIsDefault(1);
                addressMapper.updateDA(addressBook);
            } else {
                addressMapper.clearDA(openid);
                addressBook = AddressBook.builder().address(address)
                        .isDefault(1)
                        .openid(openid)
                        .phone(phone).build();
                addressMapper.save(addressBook);
            }
        }
        return number + "";
    }

    /**
     * 查询历史订单
     *
     * @return
     */
    public HistoryOrderVO selectHisOrders() {
        //获取openid
        String openid = BaseContext.getCurrentId();
        //获取订单列表
        List<Orders> outList = orderMapper.selectOut1(openid);
        if (outList.size() < 20) {
            List<Orders> outList2 = orderMapper.selectOut2(openid);
            if (outList2.size() > 20) {
                outList.addAll(outList2.subList(0, 19));
            } else {
                outList.addAll(outList2);
            }
        }
        //创建结果订单列表
        List<OrderVO> outRes = new ArrayList<>();

        //一个接单对应一个订单
        for (int i = 0; i < outList.size(); ) {

            //创建结果对象
            OrderVO orderVO = new OrderVO();

            //图片列表
            List<String> imgList = new ArrayList<>();

            //获取一个订单
            Orders order = outList.get(i);

            //拷贝到结果对象里，搞订单详细信息
            BeanUtils.copyProperties(order, orderVO, "image");

            //获取订单号
            Long number = order.getNumber();

            //搞图片
            for (int j = 0; j < outList.size(); ) {
                Orders out = outList.get(j);
                if (number.equals(out.getNumber())) {
                    String image = out.getImage();
                    if (image != null) {
                        image = serverPath + image;
                        imgList.add(image);
                    }
                    Orders remove = outList.remove(j);
                    if (remove == null) {
                        j++;
                    }
                } else {
                    j++;
                }
            }
            //获得订单图片列表
            if (imgList != null) {
                orderVO.setImages(imgList);
            }
            if (order.getImageOver() != null && !order.getImageOver().equals("")) {
                orderVO.setImageOver(serverPath + order.getImageOver());
            }
            //寻找接单信息,搞接单
            TakeOrders takeOrder = orderMapper.selectTakePeople(number);
            if (takeOrder != null) {
                orderVO.setTakeoutTime(takeOrder.getTakeorderTime());
                orderVO.setTakeTime(takeOrder.getTakeTime());
                orderVO.setDeliveryTime(takeOrder.getDeliveryTime());
            }
            String openid_ = null;
            //寻找接单人信息
            if (takeOrder != null) {
                openid_ = takeOrder.getOpenid();
            }

            AddressBook addressBook = userMapper.selectByOpenid(openid_);
            if (addressBook != null) {
                orderVO.setHelperPhone(addressBook.getPhone());
                orderVO.setHelperAddress(addressBook.getAddress());
            }
            List<OrderCount> orderCounts = orderCountMapper.selectByOrderId(order.getId());
            if (!orderCounts.isEmpty()) {
                orderVO.setOrderCounts(orderCounts);
            }
            orderVO.setOrderType(order.getOrderType());
            orderVO.setCount(order.getCount());
            orderVO.setErrorMsg(order.getErrorMsg());
            outRes.add(orderVO);
        }
        //接单结果集合
        List<OrderVO> takeRes = new ArrayList<>();

        //搞接单列表基本信息
        List<TakeOrders> orderList = takeOrderMapper.selectTakes20(openid);
        List<TakeOrders> orderList0 = takeOrderMapper.selectTakes1(openid);
        orderList.addAll(orderList0);
        if (orderList.size() < 50) {
            List<TakeOrders> orderList2 = takeOrderMapper.selectTakes2(openid);
            if (orderList2.size() > 50) {
                orderList.addAll(orderList2.subList(0, 50));
            } else {
                orderList.addAll(orderList2);
            }

        }
        //搞每个订单的订单详细信息
        //遍历接单结果
        for (int i = 0; i < orderList.size(); i++) {

            //创建返回结果对象
            OrderVO orderVO = new OrderVO();
            //获得接单
            TakeOrders takeOrder = orderList.get(i);
            //获得订单号
            Long number = takeOrder.getNumber();
            //根据接单号查询 搞好订单详细信息
            List<Orders> takeList = orderMapper.selectTakes(number);
            //创建图片列表
            List<String> imgList = new ArrayList<>();
            //先把订单详细信息确认 只需拷贝一次
            if (!takeList.isEmpty()) {
                BeanUtils.copyProperties(takeList.get(0), orderVO, new String[]{"image"});
                String image = takeList.get(0).getImage();
                if (image != null) {
                    image = serverPath + image;
                    imgList.add(image);
                }
                if (takeList.get(0).getImageOver() != null && !takeList.get(0).getImageOver().equals("")) {
                    orderVO.setImageOver(serverPath + takeList.get(0).getImageOver());
                }
                //移除
                takeList.remove(0);
            }
            //遍历订单 搞图片
            for (int j = 0; j < takeList.size(); ) {
                //获取一个订单信息
                Orders order = takeList.get(j);
                //获取图片信息
                String image = order.getImage();
                if (image != null) {
                    image = serverPath + image;
                    //添加到图片列表里
                    imgList.add(image);
                }
                //移除
                Orders remove = takeList.remove(j);
                //没有移除
                if (remove == null) {
                    j++;
                }
            }


            if (imgList != null) {
                orderVO.setImages(imgList);
            }

            //搞接单人信息
            //接单信息
            if (takeOrder != null) {
                orderVO.setTakeoutTime(takeOrder.getTakeorderTime());
                orderVO.setTakeTime(takeOrder.getTakeTime());
                orderVO.setDeliveryTime(takeOrder.getDeliveryTime());
            }

            //寻找接单人信息
            String openid_ = null;
            //寻找接单人信息
            if (takeOrder != null) {
                openid_ = takeOrder.getOpenid();
            }
            AddressBook addressBook = userMapper.selectByOpenid(openid_);
            if (addressBook != null) {
                orderVO.setHelperPhone(addressBook.getPhone());
                orderVO.setHelperAddress(addressBook.getAddress());
            }
            orderVO.setOrderType(takeOrder.getOrderType());
            orderVO.setCount(takeOrder.getCount());
            takeRes.add(orderVO);

        }
        HistoryOrderVO historyOrderVO = new HistoryOrderVO();
        historyOrderVO.setOutOrderList(outRes);
        historyOrderVO.setTakeOrderList(takeRes);
        return historyOrderVO;
    }


    /**
     * 向浏览器写图片
     *
     * @param url
     * @param response
     */
    @Transactional
    @Override
    public void download(String url, HttpServletResponse response) {
        if (url != null && url != "") {
            downloadUtil.download(basePath, url, response);
        }
    }

    /**
     * 取消订单
     *
     * @param id
     * @param cancel
     */
    @Transactional
    @Override
    public void cancel(Integer id, Integer cancel) {
        Orders orders = orderMapper.selectById(id);
        Integer amount = (int) (orders.getAmount() * 100);
        ProductInfo productInfo = productInfoService.selectByID(orders.getProductId());
        LocalDateTime now = LocalDateTime.now();
        if (orders.getProductId().equals(1)) {
            userMapper.updateCancelTimes(BaseContext.getCurrentId());
            if (amount.equals(productInfo.getNewUserPrice())) {
                activityRecordMapper.deleteByOpenidActivity(orders.getOpenid(), 1);
            }
        } else if (orders.getProductId().equals(2)) {
            if (amount.equals(productInfo.getNewUserPrice())) {
                activityRecordMapper.deleteByOpenidActivity(orders.getOpenid(), 3);
            }
        }
        orderMapper.updateCancel(id, cancel);
        orderMapper.updateTime(id, now);
        orderMapper.updateFinishTime(id, now);
        //if (orders.getIsUseCoupon() == 1) {
        //    couponBookMapper.updateAddCount(BaseContext.getCurrentId(), orders.getCouponId());
        //}
    }

    /**
     * 已取件
     *
     * @param id
     * @param received
     * @return
     */
    @Override
    @Transactional
    public Result take(Integer id, Integer received) {
        Orders orders = orderMapper.selectById(id);
        if (orders == null) {
            return Result.error("id错误");
        }
        ArrayList<Integer> list = new ArrayList<>();
        list.add(-2);
        list.add(-3);
        list.add(2);
        list.add(21);
        list.add(22);
        list.add(23);
        list.add(24);
        list.add(25);
        if (list.contains(orders.getOrderStatus())) {
            Long number = orders.getNumber();
            TakeOrders takeOrders = takeOrderService.selectOrderByNumber(number);
            String openid = takeOrders.getOpenid();
            if (!openid.equals(BaseContext.getCurrentId())) {
                return Result.error("大哥别乱搞");
            }
            LocalDateTime now = LocalDateTime.now();
            orderMapper.updateCollected(id, received);
            orderMapper.updateTime(id, now);
            orderMapper.updateTakeTime(number, now);
            return Result.success("取件成功！");
        }
        return Result.error("数据错误");
    }

    /**
     * 已送达
     *
     * @param id
     * @param reached
     * @return
     */
    @Override
    @Transactional
    public Result arrive(Integer id, Integer reached) {
        Orders orders = orderMapper.selectById(id);
        if (orders == null) {
            return Result.error("id错误");
        }
        if (orders.getOrderStatus() == 3) {
            Long number = orders.getNumber();
            TakeOrders takeOrders = takeOrderService.selectOrderByNumber(number);
            String openid = takeOrders.getOpenid();
            if (!openid.equals(BaseContext.getCurrentId())) {
                return Result.error("请不要挑战我！");
            }
            LocalDateTime now = LocalDateTime.now();
            orderMapper.updateReached(id, reached);
            orderMapper.updateTime(id, now);

            orderMapper.updateDeliveryTime(number, now);
            return Result.success("送达成功");
        }
        return Result.error("请不要挑战我！");
    }

    /**
     * 已完成
     *
     * @param id
     * @param completed
     */
    @Override
    @Transactional
    public void confirm(Integer id, Integer completed) {
        orderMapper.updateCompleted(id, completed);
        orderMapper.updateTime(id, LocalDateTime.now());
        orderMapper.updateFinishTime(id, LocalDateTime.now());
    }

    /**
     * 查询所有订单
     *
     * @return
     */
    @Override
    public HomeLists selectAll() {
        //查询所有未接订单
        List<HomeVO> list = orderMapper.selectUrgent();
        List<HomeVO> listNotUrgent = orderMapper.selectAll();
        list.addAll(listNotUrgent);
        if (list.isEmpty()) {
            //未接订单为空，查询所有已经接单的订单
            List<HomeVO> Endlist = orderMapper.selectEndAll();
            if (Endlist.size() > 30) {
                //如果单量大于30截取至30条
                Endlist = Endlist.subList(0, 30);
            }
            //手机号加码
            for (int i = 0; i < Endlist.size(); i++) {
                HomeVO orders = Endlist.get(i);
                String address = orders.getAddress();
                String phone = orders.getPhone();
                String sub = phone.substring(0, 7);
                String substring = address.substring(0, address.lastIndexOf("/")) + "/***";
                orders.setAddress(substring);
                phone = sub + "****";
                orders.setPhone(phone);
            }
            return getHomeLists(Endlist);
        } else {
            //未接订单不为空
            if (list.size() < 30) {
                //未接订单小于50条
                List<HomeVO> Endlist = orderMapper.selectEndAll();
                if (Endlist.size() < 30 - list.size()) {
                    list.addAll(Endlist);
                } else {
                    List<HomeVO> homeVOS = Endlist.subList(0, 30 - list.size());
                    list.addAll(homeVOS);
                }
            }
            //手机号加码
            for (int i = 0; i < list.size(); i++) {
                HomeVO orders = list.get(i);
                String address = orders.getAddress();
                String phone = orders.getPhone();
                String sub = phone.substring(0, 7);
                String substring = address.substring(0, address.lastIndexOf("/")) + "/***";
                orders.setAddress(substring);
                phone = sub + "****";
                orders.setPhone(phone);
            }
            return getHomeLists(list);
        }
    }

    @NotNull
    private HomeLists getHomeLists(List<HomeVO> list) {
        HomeLists homeLists = new HomeLists();
        List<HomeVO> expressList = new ArrayList<>();
        List<HomeVO> errandList = new ArrayList<>();
        Map<String, List<HomeVO>> listMap = list.stream().collect(Collectors.groupingBy(HomeVO::getOrderType));
        for (String orderType : listMap.keySet()) {
            if (orderType.equals("代取快递") || orderType.equals("加急快递")) {
                expressList.addAll(listMap.get(orderType));
            } else if (orderType.equals("代跑腿")) {
                errandList.addAll(listMap.get(orderType));
            }
        }
        homeLists.setListAll(list);
        homeLists.setExpressList(expressList);
        homeLists.setErrandList(errandList);
        return homeLists;
    }

    //接单
    @Transactional
    @Override
    public Result<String> takeOrder(Integer id) {
        //判断是否为骑手
        //openid表示当前用户
        String openid = BaseContext.getCurrentId();
        Users users = userMapper.selectByOpenId(openid);
        if (users.getType().equals(Users.NO_HELPER)) {
            //不是骑手
            return Result.error("是否成为帮手");
        }
        //查询订单号
        //是骑手
        Orders order = orderMapper.selectById(id);
        if (order.getOrderStatus() == 2) {
            return Result.error("该订单已经被接了哦~");
        }

        if (order.getOrderStatus() != 1) {
            return Result.error("大哥别乱搞");
        }
        Long number = order.getNumber();
        String openid_ = order.getOpenid();
        if (openid_.equals(openid)) {
            return Result.error("不能接自己的订单哦~");
        }
        List<Orders> orders = orderMapper.selectByopenId5(openid);
        if (orders.size() >= 5) {
            return Result.error("请完成已接订单，才能继续接单哦~");
        }
        AddressBook addressBook = addressMapper.selectByOpenid(openid);
        if (addressBook == null) {
            return Result.error("请先去个人中心完善信息哦~");
        }
        //插入到takeOrders表中
        takeOrderMapper.insert(number, openid, LocalDateTime.now());
        //更新订单状态为已接单
        orderMapper.updateOrderType(id);
        return Result.success("接单成功");
    }

    @Override
    public Orders selectOrderById(Integer id) {
        return orderMapper.selectById(id);
    }

    @Override
    public Result withdraw(String openid) {
        UserMoney userMoney = userMoneyMapper.selectById(openid);
        LocalDateTime now = LocalDateTime.now();
        if (userMoney == null) {
            return Result.error("当前余额为0，不可提现");
        }
        Integer money = userMoney.getMoney();
        if (money < 100) {
            return Result.error("当前余额不足一元，无法提现");
        }
        Integer money1 = (money / 100) * 100;
        Withdraw withdraw = withdrawMapper.selectByOpenId(openid);
        if (withdraw != null) {
            return Result.error("请不要重复提现，需要1~2工作日");
        }
        AddressBook addressBook = addressMapper.selectByOpenid(openid);
        if (addressBook == null) {
            return Result.error("请填写默认信息");
        }
        Withdraw withdraw1 = Withdraw.builder().openid(openid).withdrawMoney(money1).phone(addressBook.getPhone()).withdrawDate(now).status(0).build();
        withdrawMapper.insert(withdraw1);
        return Result.success("提现成功");
    }


    /**
     * 订单文件上传到本地
     *
     * @param files
     * @param imgs
     */
    @Transactional
    public void uploadToLocal(MultipartFile[] files, List<String> imgs) {
        for (int i = 0; i < files.length; i++) {
            String filePath = upLoadUtil.upload(basePath, files[i]);
            imgs.add(filePath);
        }
    }

    @Override
    public void update(Integer id, LocalDateTime time1) {
        orderMapper.updata(id, time1);
    }

    @Override
    public HistoryOrderVO selectPathOrders(String path) {
        //获取openid
        String openid = BaseContext.getCurrentId();
        //接单结果集合
        List<OrderVO> takeRes = new ArrayList<>();
        //搞接单列表基本信息
        List<TakeOrders> orderList = takeOrderMapper.selectPathTakes1(openid, path);
        if (orderList.size() < 20) {
            List<TakeOrders> orderList2 = takeOrderMapper.selectPathTakes2(openid, path);
            if (orderList2.size() > 10) {
                orderList.addAll(orderList2.subList(0, 9));
            } else {
                orderList.addAll(orderList2);
            }
        }
        //搞每个订单的订单详细信息
        //遍历接单结果
        for (int i = 0; i < orderList.size(); i++) {

            //创建返回结果对象
            OrderVO orderVO = new OrderVO();
            //获得接单
            TakeOrders takeOrder = orderList.get(i);
            //获得订单号
            Long number = takeOrder.getNumber();
            //根据接单号查询 搞好订单详细信息
            List<Orders> takeList = orderMapper.selectTakes(number);
            //创建图片列表
            List<String> imgList = new ArrayList<>();

            //先把订单详细信息确认 只需拷贝一次
            if (!takeList.isEmpty()) {
                BeanUtils.copyProperties(takeList.get(0), orderVO, new String[]{"image"});
                String image = takeList.get(0).getImage();
                if (image != null) {
                    image = serverPath + image;
                    imgList.add(image);
                }
                //移除
                takeList.remove(0);
            }

            //遍历订单 搞图片
            for (int j = 0; j < takeList.size(); ) {
                //获取一个订单信息
                Orders order = takeList.get(j);
                //获取图片信息
                String image = order.getImage();
                if (image != null) {
                    image = serverPath + image;
                    //添加到图片列表里
                    imgList.add(image);
                }

                //移除
                Orders remove = takeList.remove(j);
                //没有移除
                if (remove == null) {
                    j++;
                }
            }
            if (imgList != null) {
                orderVO.setImages(imgList);
            }

            //搞接单人信息
            //接单信息
            if (takeOrder != null) {
                orderVO.setTakeoutTime(takeOrder.getTakeorderTime());
                orderVO.setTakeTime(takeOrder.getTakeTime());
                orderVO.setDeliveryTime(takeOrder.getDeliveryTime());
            }

            //寻找接单人信息
            String openid_ = null;
            //寻找接单人信息
            if (takeOrder != null) {
                openid_ = takeOrder.getOpenid();
            }
            AddressBook addressBook = userMapper.selectByOpenid(openid_);
            if (addressBook != null) {
                orderVO.setHelperPhone(addressBook.getPhone());
                orderVO.setHelperAddress(addressBook.getAddress());
            }
            orderVO.setOrderType(takeOrder.getOrderType());
            takeRes.add(orderVO);
        }
        HistoryOrderVO historyOrderVO = new HistoryOrderVO();
        historyOrderVO.setTakeOrderList(takeRes);
        return historyOrderVO;
    }

    @Override
    public void image(Integer id, MultipartFile image) {
        //获取openid
        String openid = BaseContext.getCurrentId();

        //获取图片资源数组
        MultipartFile[] files = {image};
        //创建集合对象
        List<String> imgs = new ArrayList<>();
        //判断是否接收到图片
        if (image != null) {
            //存储到本地
            uploadToLocal(files, imgs);
        }


        orderMapper.updatetImage(id, imgs.get(0));
    }

    @Override
    public Result<String> takeCancel(Integer id) {
        if (id != null) {
            Orders orders = orderMapper.selectById(id);
            if (orders.getOrderStatus().equals(Orders.COLLECTED)) {
                LocalDateTime currentTime = LocalDateTime.now();
                Long number = orders.getNumber();
                TakeOrders takeOrders = takeOrderMapper.selectById(number);
                LocalDateTime referenceTime = takeOrders.getTakeorderTime();
                Duration duration = Duration.between(referenceTime, currentTime);
                long minutes = duration.toMinutes();
                if (minutes > 30) {
                    return Result.error("超过30分钟 无法取消");
                }
                takeOrderMapper.DeleteByNumber(number);
                orderMapper.updateStatus(number, Orders.TO_BE_CONFIRMED);
                return Result.success("取消成功");
            }
            return Result.error("取消失败");
        }
        return Result.error("取消失败");
    }


}
